package util;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import parser.domain.Symbol;
import main.Main;

public class ParserUtil {

	/**
	 * Computes the concatenation of length 1 of the sets in a list
	 * 
	 * @param sets
	 * @return
	 */
	public static Set<Symbol> concatSets(List<Set<Symbol>> sets) {
		Set<Symbol> result = new HashSet<>();
		Iterator<Set<Symbol>> it = sets.iterator();
		if (it.hasNext()) {
			result = it.next();
			while (it.hasNext()) {
				result = ParserUtil.concat(result, it.next());
			}
		}
		return result;
	}

	/**
	 * Computes the concatenation of length 1 of 2 sets ( s1 + s2 ).
	 * 
	 * @param s1
	 * @param s2
	 * @return a set containing the result of the concatenation
	 */
	public static Set<Symbol> concat(Set<Symbol> s1, Set<Symbol> s2) {
		Set<Symbol> result = new HashSet<>();
		for (Symbol sym1 : s1) {
			if (s2 == null || s2.size() == 0) {
				result.add(sym1);
			} else {
				if (sym1.getSymbol().equals(Main.EPSILON)) {
					for (Symbol sym2 : s2) {
						result.add(sym2);
					}
				} else {
					result.add(sym1);
				}
			}
		}
		return result;
	}
	
	/**
	 * Checks if the maps are equal.
	 * @param map
	 * @param prevMap
	 * @return
	 */
	public static boolean stepEquals(Map<Symbol, Set<Symbol>> map,
			Map<Symbol, Set<Symbol>> prevMap) {
		Set<Symbol> set;
		Set<Symbol> prevSet;
		for (Symbol sym : map.keySet()) {
			set = map.get(sym);
			prevSet = prevMap.get(sym);
			if (set.size() != prevSet.size()) {
				return false;
			}

			for (Symbol s : set) {
				if (!prevSet.contains(s)) {
					return false;
				}
			}

			for (Symbol s : prevSet) {
				if (!set.contains(s)) {
					return false;
				}
			}
		}
		return true;
	}
	
	public static Map<Symbol, Set<Symbol>> copyStepMap(Map<Symbol, Set<Symbol>> map){
		Map<Symbol, Set<Symbol>> copy = new HashMap<Symbol, Set<Symbol>> ();
		for(Symbol s : map.keySet()){
			copy.put(s, new HashSet<Symbol>(map.get(s)));
		}
		return copy;
	}
	
}
